<?php

namespace app\model;

use app\Log;
use think\facade\Db;
use think\helper\Str;
use think\Model;
use think\model\relation\HasOne;

class UserScoreRecharge extends Model
{
    public function add(): array
    {
        $param = request()->post();
        if ($param['number'] <= 0) throw new \Exception('发放金额必须大于0', 10001);
        $user = app(User::class);
        $car = app(UserCar::class);
        //查看是否已注册手机号
        $account = $user->where('mobile', $param['mobile'])->find();
        $store = app(Account::class)->with(['store'])->find($param['aid']);
        if (empty($store)) throw new \Exception('门店账号不存在', 10001);
        if (bcdiv($store->balance, 100, 2) < $param['number']) throw new \Exception('门店余额不足', 10001);
        $this->startTrans();
        if (empty($account)) {
            $user->save([
                'mobile' => $param['mobile'],
                'username' => $param['mobile'],
                'balance' => (int)bcmul($param['number'], 100),
                'state' => 1,
                'is_del' => 1,
                'supplier_id' => $store->supplier_id,
                'store_id' => $store->store_id
            ]);
            $uid = $user->id;
        } else {
            $account->inc('balance', (int)bcmul($param['number'], 100))->save();
            $uid = $account->id;
        }
        if (!empty($param['car_number'])) {
            $number = $car->where(['uid' => $uid, 'car_number' => $param['car_number']])->count();
            if ($number < 1)
                $car->save([
                    'car_number' => $param['car_number'],
                    'uid' => $uid,
                    'is_del' => 1,
                    'type' => strlen($param['car_number']) < 8 ? 2 : 1
                ]);
        }
        //生成充值订单
        $this->save([
            "rechange_code" => date("YmdHis") . Str::random(6, 1),
            "uid" => $uid,
            "aid" => $store->id,
            "sid" => $store->store_id,
            "pid" => $store->supplier_id,
            "car_number" => $param['car_number'],
            "remark" => $param['remark'],
            "number" => (int)bcmul($param['number'], 100),
            "state" => 1
        ]);
        if ($store['type'] == 2) {
            app(Store::class)->where(['id' => $store->store_id])->dec('balance', (int)bcmul($param['number'], 100))->save();
//            dd( app(Account::class)->where(['store_id' => $store->store_id])->select()->toArray());
            app(Account::class)->where(['store_id' => $store->store_id, 'type' => 2])->dec('balance', (int)bcmul($param['number'], 100))->save();
        } else {
            //扣减余额
            $store->dec('balance', (int)bcmul($param['number'], 100))->save();
        }
        app(UserBalance::class)->save([
            "uid" => $uid,
            "content" => $store['store']['name'] . "赠送积分：" . $param['number'],
            "number" => bcmul($param['number'], 100),
            "type" => 1
        ]);
        if ($uid != 15)
            //记录余额有效期数据
            app(UserValidateBalance::class)->addBalance($uid, (int)bcmul($param['number'], 100));
        $this->commit();
        return $this->toArray();
    }

    public function changeAll($param)
    {
        $log = new Log("all_insert");
//        $param = request()->post('balance');
        $user = app(User::class);
        $userBalance = app(UserBalance::class);
        $store = app(Account::class)->with(['store'])->find($param[0]['aid']);
        if (empty($store)) throw new \Exception('门店账号不存在', 10001);
        $total = array_sum(array_column($param, 'number'));
//        dd($total);
        if (bcdiv($store->balance, 100, 2) < $total) throw new \Exception('门店余额不足', 10001);
        $items = [];
        $userItems = [];
        foreach ($param as $value) {
            $uid = $user->where('mobile', $value['mobile'])->value('id');
            if (empty($uid)) {
                $uid = $user->insertGetId([
                    'mobile' => $value['mobile'],
                    'username' => $value['mobile'],
                    'balance' => 0,
                    'state' => 1,
                    'is_del' => 1,
                    'supplier_id' => $store->supplier_id,
                    'store_id' => $store->store_id,
                    "create_time" => date("Y-m-d H:i:s"),
                    "update_time" => date("Y-m-d H:i:s")
                ]);
            }
            if (!isset($userItems[$uid]))
                $userItems[$uid] = ['id' => $uid, "balance" => (int)bcmul($value['number'], 100)];
            else $userItems[$uid]['balance'] += (int)bcmul($value['number'], 100);
            $items[] = [
                "rechange_code" => date("YmdHis") . Str::random(6, 1),
                "uid" => $uid,
                "aid" => $store->id,
                "sid" => $store->store_id,
                "pid" => $store->supplier_id,
                "car_number" => $value['car_number'],
                "remark" => $value['remark'],
                "number" => (int)bcmul($value['number'], 100),
                "state" => 1
            ];
        }
//        dd($userItems);
        $this->startTrans();
        $this->saveAll($items);
        if ($store['type'] == 2) {
            app(Store::class)->where(['id' => $store->store_id])->dec('balance', (int)bcmul($total, 100))->save();
            app(Account::class)->where(['store_id' => $store->store_id, 'type' => 2])->dec('balance', (int)bcmul($total, 100))->save();
        } else {
            //扣减余额
            $store->dec('balance', (int)bcmul($total, 100))->save();
        }
        $bal = [];
        foreach ($userItems as &$value) {
            $bal[] = [
                "uid" => $value['id'],
                "content" => $store['store']['name'] . "赠送积分：" . bcdiv($value['balance'], 100),
                "number" => $value['balance'],
                "type" => 1
            ];
            $value['balance'] = Db::raw("balance+$value[balance]");
        }
        $userBalance->saveAll($bal);
        $user->saveAll(array_values($userItems));
        app(UserValidateBalance::class)->addMore($bal);
        $this->commit();
        $log->write(['user_item' => $userItems]);
        return $items;
    }

    public function refund(): array
    {
        $data = $this->with(['user', 'supplier', 'store', 'account'])->findOrFail(request()->param("id"));
        $this->startTrans();
        if ($data['state'] == 1) {
            $user = $data->user;
            if ($user['balance'] < $data['number'] && $user['id'] != 15) throw new \Exception('用户余额不足', 10001);
            $user->dec('balance', $data['number'])->save();
//            $data->account->inc('balance', $data['number'])->save();
            if ($data->account['type'] === 2) {
                $data->account->where(['store_id' => $data->account->store_id, 'type' => 2])->inc('balance', $data['number'])->save();
                $data->store->inc('balance', $data['number'])->save();
            } else {
                $data->account->inc('balance', $data['number'])->save();
            }
            $data->save([
                'state' => 2
            ]);
            app(UserBalance::class)->save([
                "uid" => $user['id'],
                "content" => $data->store['name'] . "回收积分：" . bcdiv($data['number'], 100),
                "number" => $data['number'],
                "type" => 3
            ]);
            if ($user['id'] != 15)
                app(UserValidateBalance::class)->decBalance($user['id'], $data['number'], $data['create_time']);
        }
        $this->commit();
        return $data->toArray();
    }

    public function user(): HasOne
    {
        return $this->hasOne(User::class, 'id', 'uid');
    }

    public function supplier(): HasOne
    {
        return $this->hasOne(Supplier::class, 'id', 'pid');
    }

    public function store(): HasOne
    {
        return $this->hasOne(Store::class, 'id', 'sid');
    }

    public function account(): HasOne
    {
        return $this->hasOne(Account::class, 'id', 'aid');
    }

    public function getPage(): array
    {
        $param = request()->param();
        $page = $param['page'] ?? 1;
        $limit = $param['limit'] ?? 50;
        $admin = request()->admin;
        $where = $this->with(['user', 'supplier', 'store', 'account'])->when(!empty($param['mobile']), function ($query) use ($param) {
            $uid = User::where('mobile', '=', $param['mobile'])->column("id");
            $query->whereIn('uid', $uid);
        })->when(!empty($param['state']), function ($query) use ($param) {
            $query->where('state', $param['state']);
        })->when(!empty($param['car_number']), function ($query) use ($param) {
            $query->where('car_number', $param['car_number']);
        })->when(!empty($param['create_time']), function ($query) use ($param) {
            $query->whereBetween('create_time', [$param['create_time'][0] . " 00:00:00", $param['create_time'][1] . " 23:59:59"]);
        })->when(!empty($param['pid']), function ($query) use ($param) {
            $query->where('pid', $param['pid']);
        })->when(!empty($param['sid']), function ($query) use ($param) {
            $query->where('sid', $param['sid']);
        })->when(!empty($admin) && $admin['is_admin'] === 2 && empty($param['sid']) && empty($param['pid']), function ($query) {
            $query->where("sid", "<>", 13);
        })->when(!empty($param['aid']), function ($query) use ($param) {
            $query->where('aid', $param['aid']);
        })->when(!empty($param['store_id']), function ($query) use ($param) {
            $query->where('sid', $param['store_id']);
        })->when(!empty($param['mobile']), function ($query) use ($param) {
            $uid = User::where("mobile", $param['mobile'])->column("id");
            $query->whereIn('uid', $uid);
        })->when(!empty($param['supplier_id']), function ($query) use ($param) {
            $query->where('pid', $param['supplier_id']);
        });
        $data = $where->order('create_time', 'desc')->paginate(['list_rows' => $limit, 'page' => $page])->toArray();
        return ['lst' => $data['data'], 'total' => $data['total'], 'totalPage' => $data['last_page']];
    }

    public function chat(): array
    {
        $param = request()->param();
        $admin = request()->admin;
        $where = $this->when(!empty($param['mobile']), function ($query) use ($param) {
            $uid = User::where('mobile', '=', $param['mobile'])->column("id");
            $query->whereIn('uid', $uid);
        })->when(!empty($param['state']), function ($query) use ($param) {
            $query->where('state', $param['state']);
        })->when(!empty($param['car_number']), function ($query) use ($param) {
            $query->where('car_number', $param['car_number']);
        })->when(!empty($param['create_time']), function ($query) use ($param) {
            $query->whereBetween('create_time', [$param['create_time'][0] . " 00:00:00", $param['create_time'][1] . " 23:59:59"]);
        })->when(!empty($param['pid']), function ($query) use ($param) {
            $query->where('pid', $param['pid']);
        })->when(!empty($param['sid']), function ($query) use ($param) {
            $query->where('sid', $param['sid']);
        })->when(!empty($param['aid']), function ($query) use ($param) {
            $query->where('aid', $param['aid']);
        })->when(!empty($param['store_id']), function ($query) use ($param) {
            $query->where('sid', $param['store_id']);
        })->when(!empty($param['mobile']), function ($query) use ($param) {
            $uid = User::where("mobile", $param['mobile'])->column("id");
            $query->whereIn('uid', $uid);
        })->when(!empty($param['supplier_id']), function ($query) use ($param) {
            $query->where('pid', $param['supplier_id']);
        })->when(!empty($admin) && $admin['is_admin'] === 2 && empty($param['sid']) && empty($param['pid']), function ($query) {
            $query->where("sid", "<>", 13);
        })->group('state')->field("sum(number) number,count(*) total,state")->select()->toArray();
        return array_map(function ($item) {
            $item['number'] = (float)bcdiv($item['number'], 100, 2);
            return $item;
        }, array_column($where, null, 'state'));
    }

    public function download(): array
    {
        $data = $this->getPage();
        $result = array_map(function ($item) {
            return [
                $item['rechange_code'],
                $item['user']['mobile'],
                (float)bcdiv($item['number'], 100, 2),
                $item['store']['name'],
                $item['supplier']['name'],
                $item['account']['name'],
                $item['remark'],
                $item['car_number'],
                $item['create_time'],
                $item['state'] == 1 ? '已发放' : '已回收'
            ];
        }, $data['lst']);
        $totalPage = $data['totalPage'];
        $header = [
            '发放单号',
            '手机号',
            '发放金额',
            '门店名称',
            '渠道名称',
            '充值人',
            '备注',
            '车牌号',
            '充值时间',
            '状态'
        ];
        $title = ["积分发放记录"];
        $file = "积分发放记录";
        return compact("result", "header", "title", "totalPage", "file");
    }
}
